Skip to content

Conversation

@alexwarren
Copy link
Collaborator

This PR adds a language picker to code blocks.

Create a code block, and there is a new drop-down icon to the right of the auto-detected language:

image

Click the language, or press Ctrl+; (PC) or Cmd+; (Mac) to open the language picker:

image

Start typing to filter down the list of languages:

image

Click a language, or select one with the arrow keys to set it. Or keep typing if the language is not listed, and press Enter.

The language of the code block is updated, and the relevant syntax highlighting is applied:

image

In Markdown view, the language has been set:

image

For demo purposes there is a hard-coded list of languages. For production use on Stack Overflow, we'll inject the list of languages as part of the highlighting options when instantiating the editor.

@changeset-bot
Copy link

changeset-bot bot commented Apr 22, 2025

🦋 Changeset detected

Latest commit: 83592f1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@stackoverflow/stacks-editor Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@netlify
Copy link

netlify bot commented Apr 22, 2025

Deploy Preview for stacks-editor ready!

Name Link
🔨 Latest commit 83592f1
🔍 Latest deploy log https://app.netlify.com/sites/stacks-editor/deploys/680f59e467a5250008b32900
😎 Deploy Preview https://deploy-preview-429--stacks-editor.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

NOTE this only works in tests at the moment, need to figure out adding the plugin to the real editor
Copy link
Contributor

@dancormier dancormier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice enhancement @alexwarren. This is something I've wanted personally, so I'm selfishly happy to see this finally coming.

I've performed a partial review and made some suggestions on the markup. Happy to discuss the suggestion further if you'd like a little Stacks/accessibility help.

I also noticed two bugs:

  1. Any string can be set as the language

20250422-053427

  1. Languages not included in the predefined languages are set unexpectedly.

Note

After reviewing, I realized this was mentioned in the description:

Or keep typing if the language is not listed, and press Enter.

I'd consider this on that bug/feature line but I wouldn't cry if this stayed as-is.

20250422-054014

These two bugs probably shouldn't be show-stoppers, but I figured they were worth mentioning.

Comment on lines 44 to 53
<div class="ps-absolute t24 r4 js-language-input">
<div class="ps-relative mb8">
<label class="v-visible-sr" for="example-search">Search</label>
<input type="text" class="s-input s-input__search fs-caption js-language-input-textbox" placeholder="Search for a language" contenteditable="false" />
<span class="s-input-icon s-input-icon__search svg-icon-bg iconSearchSm"></span>
</div>
<div class="s-card fs-caption c-pointer py4 px4 js-language-dropdown-container">
<ul class="s-menu js-language-dropdown"></ul>
</div>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Use .s-popover as the container for the language selector

Note

FWIW, I'm not 100% on this suggestion. I'd suggest running it by a designer.

It seems we've added some custom code to show/hide the language selector when we could use the functionality built into Stacks by instead using the .s-popover component. This would allow us to simplify the functional code in this file and get the benefits that come from using the popover (things like automatic layout). This would potentially change the design of the language selector unless we add a bunch of atomic styling classes to the popover, but there could be a styling middle-ground that allows us to use the .s-popover element

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ProseMirror doesn't play nicely with things that try to change HTML so it won't play nicely with the built-in popover component. It really needs the state (i.e. whether the popover is open or not) to be in ProseMirror, which is why we're manually controlling it here, rather than letting anything external handle that. Combined with the different design here, I don't think using .s-popover would work well for this.

Copy link
Contributor

@dancormier dancormier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for making the UI changes @alexwarren. They work well. I only found a couple of minor issues (one mentioned inline; the other here) that I don't consider blockers 🎉

Return creates new line unexpectedly

When pressing return when inputting an arbitrary string into the language selector, a new line is added to the editor. In this gif, I've removed most of what comes before the code block to demonstrate:

20250425-020947

Comment on lines +76 to +79
textbox.addEventListener(
"mousedown",
this.onLanguageInputMouseDown.bind(this)
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this listener necessary? What's the case where the event of a user clicking in the field needs to be prevented?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It prevents ProseMirror from erroring when you triple-click the textbox (as you might if you want to select all the text in it). Added a comment so this is clearer.

@alexwarren
Copy link
Collaborator Author

Return creates new line unexpectedly

When pressing return when inputting an arbitrary string into the language selector, a new line is added to the editor. In this gif, I've removed most of what comes before the code block to demonstrate:

Thanks, I've checked in a fix for this too.

@alexwarren alexwarren requested a review from dancormier April 28, 2025 10:35
@alexwarren alexwarren merged commit 24319c8 into main Apr 28, 2025
5 checks passed
@alexwarren alexwarren deleted the awarren/code-block-language-picker branch April 28, 2025 14:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants